package com.lsh.oms.provider.service.payment;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lsh.base.common.model.CommonResult;
import com.lsh.oms.api.model.payment.BillPaymentDTO;
import com.lsh.oms.api.model.payment.OrderPayBillRequestDTO;
import com.lsh.oms.api.model.payment.OrderRequestDTO;
import com.lsh.oms.api.service.payment.IOrderPaymentBillRestService;
import com.lsh.oms.core.constant.ReturnCode;
import com.lsh.oms.core.enums.PayChannel;
import com.lsh.oms.core.enums.PayStatus;
import com.lsh.oms.core.exception.BusinessException;
import com.lsh.oms.core.exception.ExceptionStatus;
import com.lsh.oms.core.model.payment.BillPaymentInfo;
import com.lsh.oms.core.service.payment.BillPaymentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Project Name: lsh-oms
 *
 * @author peter
 * @date 19/4/15
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Service(protocol = "rest", timeout = 30000)
@Path("order/pay/bill")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({ContentType.APPLICATION_JSON_UTF_8})
@Slf4j
public class OrderPaymentBillRestServiceImpl implements IOrderPaymentBillRestService {

    @Autowired
    private BillPaymentService billPaymentService;

    @POST
    @Path("query")
    @Override
    public CommonResult<JSONObject> orderPaymentBills(OrderPayBillRequestDTO bIllDTO) {

        String uid = bIllDTO.getUid();
        Integer start = bIllDTO.getStart();
        Integer page = bIllDTO.getPage();

        CommonResult<JSONObject> commonResult = new CommonResult<>();
        JSONObject data = new JSONObject();
        data.put("start", start);
        data.put("page", page);
        try {
            String payChannel = bIllDTO.getPayChannel();
            if (StringUtils.isEmpty(payChannel)) {
                payChannel = PayChannel.BALANCE_PAYMENT.getCode();
            }

            if (!this.validateParams(bIllDTO)) {
                throw new BusinessException(ReturnCode.REQUEST_FAIL, "参数检查错误 下单数据有误");
            }

            Integer allNum = this.totalNum(uid, payChannel);
            if (null == allNum || allNum == 0) {
                this.dataBuilder(data);

                commonResult.setCode(ReturnCode.REQUEST_SUCCESS);
                commonResult.setData(data);
                return commonResult;
            }

            List<BillPaymentInfo> billPaymentInfos = this.billPaymentService.selectPageList(uid, start, page, Integer.valueOf(payChannel));

            if (CollectionUtils.isEmpty(billPaymentInfos)) {

                this.dataBuilder(data, allNum, Collections.EMPTY_LIST);
                commonResult.setCode(ReturnCode.REQUEST_SUCCESS);
                commonResult.setData(data);
                return commonResult;
            }

            List<BillPaymentDTO> paymentDTOS = new ArrayList<>();
            for (BillPaymentInfo info : billPaymentInfos) {
                BillPaymentDTO dto = new BillPaymentDTO();
                BeanUtils.copyProperties(info, dto);
                dto.setOrderCode(info.getBillCode());
                paymentDTOS.add(dto);
            }

            this.dataBuilder(data, allNum, paymentDTOS);

            commonResult.setCode(ReturnCode.REQUEST_SUCCESS);
            commonResult.setData(data);
        } catch (BusinessException e) {
            commonResult.setCode(e.getCode());
            commonResult.setMessage(e.getMessage());
            log.error("[查询余额支付流水信息] 业务异常code : " + e.getCode() + ",异常信息: " + e.getMessage(), e);
        } catch (Exception e) {
            commonResult.setCode(ReturnCode.SYS_ERROR);
            commonResult.setMessage(ExceptionStatus.E3001001.getMessage());
            log.error("[查询余额支付流水信息] 异常code : " + ExceptionStatus.E3001001.getCode() + ",异常信息: " + e.getMessage(), e);
        }

        return commonResult;
    }

    @POST
    @Path("query/orderCodes")
    @Override
    public CommonResult<JSONArray> orderPaymentInfo(OrderRequestDTO orderRequestDTO) {

        CommonResult<JSONArray> commonResult = new CommonResult<>();
        JSONArray data = new JSONArray();
        try {

            List<BillPaymentInfo> billPaymentInfos = this.billPaymentService.selectListBySequences(orderRequestDTO.getPaySequences());
            if (CollectionUtils.isEmpty(billPaymentInfos)) {
                throw new BusinessException(ReturnCode.REQUEST_FAIL, "匹配结果为空");
            }

            for (BillPaymentInfo dto : billPaymentInfos) {
                JSONObject item = new JSONObject();
                item.put("paySequence", dto.getPaySequence());
                item.put("orderCode", dto.getBillCode());
                data.add(item);
            }

            commonResult.setCode(ReturnCode.REQUEST_SUCCESS);
            commonResult.setData(data);
        } catch (BusinessException e) {
            commonResult.setCode(e.getCode());
            commonResult.setMessage(e.getMessage());
            log.error("[查询余额支付流水信息] 业务异常code : " + e.getCode() + ",异常信息: " + e.getMessage(), e);
        } catch (Exception e) {
            commonResult.setCode(ReturnCode.SYS_ERROR);
            commonResult.setMessage(ExceptionStatus.E3001001.getMessage());
            log.error("[查询余额支付流水信息] 异常code : " + ExceptionStatus.E3001001.getCode() + ",异常信息: " + e.getMessage(), e);
        }

        return commonResult;
    }

    /**
     * @param uid
     * @param payChannel
     * @return
     */
    private int totalNum(String uid, String payChannel) {

        BillPaymentInfo billFilter = new BillPaymentInfo();
        billFilter.setIsValid(1);
        billFilter.setUid(uid);
        billFilter.setPayChannelType(Integer.valueOf(payChannel));
        billFilter.setPayStatus(PayStatus.PAID.getValue());

        return billPaymentService.countByFilter(billFilter);
    }


    /**
     * @param data
     */
    private void dataBuilder(JSONObject data) {
        this.dataBuilder(data, 0, Collections.EMPTY_LIST);
    }

    /**
     * @param data
     * @param num
     * @param paymentDTOS
     */
    private void dataBuilder(JSONObject data, Integer num, List<BillPaymentDTO> paymentDTOS) {
        if (null == num) {
            num = 0;
            paymentDTOS = Collections.EMPTY_LIST;
        } else if (CollectionUtils.isEmpty(paymentDTOS)) {
            paymentDTOS = Collections.EMPTY_LIST;
        }

        data.put("num", num);
        data.put("billPaymentInfos", paymentDTOS);
    }

    /**
     * @param bIllDTO
     * @return
     */
    private boolean validateParams(OrderPayBillRequestDTO bIllDTO) {

        String uid = bIllDTO.getUid();
        Integer start = bIllDTO.getStart();
        Integer page = bIllDTO.getPage();

        if (StringUtils.isEmpty(uid)) {
            return false;
        }

        if (null == start) {
            bIllDTO.setStart(0);
        }

        if (null == page) {
            bIllDTO.setPage(10);
        }

        return true;
    }
}
